import { useGLTF } from "@react-three/drei";
import { PrimitiveProps } from "@react-three/fiber";
import { useEffect, useRef } from "react";
import { MathUtils } from "three";

export default function Rocket(props: Omit<PrimitiveProps, "object">) {
  const rocket = useGLTF("/rocket.glb") as any;
  const refRocket = useRef<any>();
  const temp = useRef({
    time: 0,
    v: 0,
    f: 0,
    a: 0,
    m: 38700,
    maxF: 92108,
    maxV: 79,
    boost: true,
    start: false,
  });

  useEffect(() => {
    props.bus.current.addEventListener("startBoost", () => {
      temp.current.start = true;
    });
    const rocketName = ["次火箭", "主火箭"];
    const boostName = ["推进器1", "推进器3", "推进器2", "推进器4"];
    props.bus.current.addEventListener("update", (event) => {
      const { dt, time } = event;
      if (time > 2.5) {
        const delta = time - 2.5;
        const v = 5;
        rocket.nodes[boostName[0]].position.y -= Math.pow(delta, 2) * v;
        rocket.nodes[boostName[0]].position.x -= 9.8 * dt * Math.random();
        rocket.nodes[boostName[0]].position.z -= 9.8 * dt * Math.random();

        rocket.nodes[boostName[0]].rotation.z += dt * Math.PI * Math.random();
        rocket.nodes[boostName[0]].rotation.y += dt * Math.PI * Math.random();

        rocket.nodes[boostName[1]].position.y -= Math.pow(delta, 2) * v;
        rocket.nodes[boostName[1]].position.x -= 9.8 * dt * Math.random();
        rocket.nodes[boostName[1]].position.z += 9.8 * dt * Math.random();

        rocket.nodes[boostName[1]].rotation.z += dt * Math.PI * Math.random();
        rocket.nodes[boostName[1]].rotation.y -= dt * Math.PI * Math.random();

        rocket.nodes[boostName[2]].position.y -= Math.pow(delta, 2) * v;
        rocket.nodes[boostName[2]].position.x -= 9.8 * dt * Math.random();

        rocket.nodes[boostName[2]].rotation.z = dt * Math.PI * Math.random();
        rocket.nodes[boostName[2]].rotation.x += dt * Math.PI * Math.random();

        rocket.nodes[boostName[3]].position.y -= Math.pow(delta, 2) * v;
        rocket.nodes[boostName[3]].position.x -= 9.8 * dt * Math.random();

        rocket.nodes[boostName[3]].rotation.z += dt * Math.PI * Math.random();
        rocket.nodes[boostName[3]].rotation.x -= dt * Math.PI * Math.random();
      }
      if (temp.current.start) {
        let { v, f, a, m, maxV, maxF, boost } = temp.current;
        if (v < maxV && boost) {
          if (f < maxF) {
            f += (maxF - f) * 500 * dt;
          }
          a = f / m;
        } else {
          boost = false;
          f = 0;
          a = 0;
        }
        if (v > maxV * 0.3) {
          rocket.nodes[rocketName[0]].position.y -= v * 2 * dt;
          rocket.nodes[rocketName[0]].position.x -= 9.8 * dt * Math.random();
          rocket.nodes[rocketName[0]].position.z -= 9.8 * dt * Math.random();
          rocket.nodes[rocketName[0]].rotation.z +=
            dt * Math.PI * Math.random();
          rocket.nodes[rocketName[0]].rotation.y +=
            dt * Math.PI * Math.random();
        }
        v += a * dt;
        props.refTarget.current.position.y += v * dt * 10;
        temp.current.v = v;
        temp.current.f = f;
        temp.current.a = a;
        temp.current.m = m;
        temp.current.boost = boost;
      }

      refRocket.current.position.set(
        MathUtils.randFloatSpread(0.0025),
        MathUtils.randFloatSpread(0.0025),
        MathUtils.randFloatSpread(0.0025)
      );
    });
  }, []);
  return (
    <group ref={props.refTarget}>
      <primitive
        object={rocket.scene}
        {...props}
        ref={refRocket}
        scale={[0.01, 0.01, 0.01]}
        rotation={[0, (Math.PI * 90) / 180, 0]}
      />
    </group>
  );
}
